package com.example.ethereum.controller;

import com.example.ethereum.dto.*;
import com.example.ethereum.service.ContractService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.math.BigInteger;

@Slf4j
@Api(tags = "智能合约管理接口")
@RestController
@RequestMapping("/api/contract")
public class ContractController {

    @Autowired
    private ContractService contractService;

    /**
     * 部署智能合约
     */
    @ApiOperation(value = "部署智能合约", notes = "部署一个新的ERC20代币合约到以太坊网络")
    @PostMapping("/deploy")
    public ResponseEntity<ApiResponse<String>> deployContract(
            @ApiParam(value = "合约部署请求参数", required = true) @RequestBody ContractDeployRequest request) {
        try {
            String contractAddress = contractService.deployContract(request);
            return ResponseEntity.ok(ApiResponse.success("Contract deployed successfully", contractAddress));
        } catch (Exception e) {
            log.error("Error deploying contract", e);
            return ResponseEntity.badRequest()
                    .body(ApiResponse.error("Failed to deploy contract: " + e.getMessage()));
        }
    }

    /**
     * 铸币
     */
    @ApiOperation(value = "铸币", notes = "向指定地址铸造新的代币（仅合约owner可调用）")
    @PostMapping("/mint")
    public ResponseEntity<ApiResponse<String>> mint(
            @ApiParam(value = "铸币请求参数", required = true) @RequestBody MintRequest request) {
        try {
            String txHash = contractService.mint(request);
            return ResponseEntity.ok(ApiResponse.success("Mint transaction submitted", txHash));
        } catch (Exception e) {
            log.error("Error minting tokens", e);
            return ResponseEntity.badRequest()
                    .body(ApiResponse.error("Failed to mint tokens: " + e.getMessage()));
        }
    }

    /**
     * 销毁代币
     */
    @ApiOperation(value = "销毁代币", notes = "销毁指定数量的代币。如果fromAddress为空，则销毁调用者自己的代币")
    @PostMapping("/burn")
    public ResponseEntity<ApiResponse<String>> burn(
            @ApiParam(value = "销毁请求参数", required = true) @RequestBody BurnRequest request) {
        try {
            String txHash = contractService.burn(request);
            return ResponseEntity.ok(ApiResponse.success("Burn transaction submitted", txHash));
        } catch (Exception e) {
            log.error("Error burning tokens", e);
            return ResponseEntity.badRequest()
                    .body(ApiResponse.error("Failed to burn tokens: " + e.getMessage()));
        }
    }

    /**
     * 转账
     */
    @ApiOperation(value = "转账", notes = "将代币从当前账户转账到指定地址")
    @PostMapping("/transfer")
    public ResponseEntity<ApiResponse<String>> transfer(
            @ApiParam(value = "转账请求参数", required = true) @RequestBody TransferRequest request) {
        try {
            String txHash = contractService.transfer(request);
            return ResponseEntity.ok(ApiResponse.success("Transfer transaction submitted", txHash));
        } catch (Exception e) {
            log.error("Error transferring tokens", e);
            return ResponseEntity.badRequest()
                    .body(ApiResponse.error("Failed to transfer tokens: " + e.getMessage()));
        }
    }

    /**
     * 查询余额
     */
    @ApiOperation(value = "查询余额", notes = "查询指定地址在指定合约中的代币余额")
    @GetMapping("/balance")
    public ResponseEntity<ApiResponse<String>> getBalance(
            @ApiParam(value = "合约地址", required = true) @RequestParam String contractAddress,
            @ApiParam(value = "账户地址", required = true) @RequestParam String address) {
        try {
            BigInteger balance = contractService.getBalance(contractAddress, address);
            return ResponseEntity.ok(ApiResponse.success("Balance retrieved", balance.toString()));
        } catch (Exception e) {
            log.error("Error getting balance", e);
            return ResponseEntity.badRequest()
                    .body(ApiResponse.error("Failed to get balance: " + e.getMessage()));
        }
    }
}

